from typing import Optional, Union, List

import uvicorn
from fastapi import FastAPI, Cookie, Header, Response, Path, HTTPException,status,Request
from fastapi.responses import JSONResponse
from fastapi.openapi.docs import get_swagger_ui_html
from pydantic import BaseModel, Field
from starlette.staticfiles import StaticFiles

# 创建 FastAPI 应用实例，并把默认的/docs请求禁用
# debug表示是否开启调试模式，默认是False
app = FastAPI(docs_url=None,debug=True)
app.mount("/static", StaticFiles(directory="../static"), name="static")    # 静态文件

@app.get("/docs", include_in_schema=False)
def custom_swagger_ui():
    return get_swagger_ui_html(
        openapi_url = "/openapi.json",
        title = "Swagger UI for FastAPI",
        swagger_js_url="/static/swagger-ui-bundle.min.js",
        swagger_css_url="/static/swagger-ui.min.css"
    )

class UserBase(BaseModel):
    id: Optional[int] = None
    username: str
    fullname: Optional[str] = None
    description: Optional[str] = None

class UserIn(UserBase):
    password: str

class UserOut(UserBase):
    ... # 这里使用...表示这里面不需要定义任何属性

# status_code=201表示创建成功的状态码



users = {
    "x": {"id": 0},
    "a": {"id": 1,"username": "a"},
    "b": {"id": 2,"username": "b","password": "bbb"},
    "c": {"id": 3,"username": "c","password": "ccc", "description": "default"},
    "d": {"id": 4,"username": "d","password": "ddd", "description": "user ddd"},
    "e": {"id": 5,"username": "e","password": "eee", "description": "user eee", "fullname": "Mary Water"},
}

class ErrorMessage(BaseModel):
    error_code: int
    message: str


# 此处我们加上responses参数的话，在Swagger ui中就可以显出现来对应不同的状态码和响应信息
@app.post("/users",status_code=201,response_model=UserOut,responses = {
    400: {"model": ErrorMessage},
    401: {"model": ErrorMessage}
})
async def create_user(user: UserIn):
    if users.get(user.username,None):
        error_message = ErrorMessage(error_code=400,message=f"用户 {user.username} 已存在!")
        return JSONResponse(status_code=400,content=error_message.model_dump())
    user_dict = user.model_dump()
    user_dict.update({"id": 10})
    return user_dict


class UserNotFoundException(Exception):
    def __init__(self,username:str):
        self.username = username

@app.exception_handler(UserNotFoundException)
# 这里的异常处理函灵敏中需要添加两个参数request和exc 分别表示请求对象和异常对象
# 在这个异常处理函数中返回一个结果给到用户
async def user_not_found_exception_handler(request:Request,exc:UserNotFoundException):
    # 这里使用JSONResponse组装返回
    return JSONResponse(status_code=404,content={"error_code":404,"message":f"用户{exc.username}不存在!"})

@app.get("/users/{username}",status_code=200,response_model=UserOut)
async def get_user(username:str = Path(...)):
    user = users.get(username,None)
    if user:
        return user
    # 抛出异常
    # FastAPI的异常
    # raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,detail=f"用户{username}不存在!")
    # 自定义异常
    raise UserNotFoundException(username)



if __name__ == '__main__':
    uvicorn.run("main:app", host="127.0.0.1", port=8009, reload=True)